<script setup="setup">
import { $menuUtils, $utils } from '@jzl/utils';
import { DFT_ICONS } from '@jzl/icons';
import { reactive, ref, toRefs, watch } from 'vue';
import _ from 'lodash';
import { api } from '@jzl/api';

const emit = defineEmits(['select', 'actionCreate', 'actionUpdate', 'actionRemove', 'refreshTid' ]);
const props = defineProps({
  appId: Number,
  tid: [ Number, String ],
  treeData: Array,
  expandedKeys: {
    type: Array,
    default: () => []
  },
  tty: {
    type: [Number, String],
    default: 1
  }
});

const {
  currentData,
  // form,
  expandedKeys,
  popData
} = toRefs(
  reactive({
    currentData: null,
    // form: {}, // _.cloneDeep(DEFAULT_FORM),
    expandedKeys: [],
    popData: null
  })
);

const nodeMorePopoverShow = ref(false);
const nodeMorePopoverTrigger = ref(null);
const menutreeRef = ref(null);
const treeSetting = ref({
  children: 'subs',
  label: 'name',
  'icon-class': 'hello-icon'
});
const currentSelectedId = ref(null);

const filterNode = (value, data) => {
  if (!value) return true;
  if (!data.name) return true;
  return data.name.indexOf(value) !== -1;
};

const getNodeIconFont = (data) => {
  let type = _.get(data, 'content_type');

  if (type === 'PER_FORM') {
    return DFT_ICONS.formview;
  } else if (type === 'PER_REPORT') {
    return DFT_ICONS.chartBar;
  } else if (type === 'PER_API') {
    return DFT_ICONS.api;
  } else {
    return $menuUtils.getIconFont(data);
  }
};

const getNodeName = (data) => {
  let name = _.get(data, 'name');
  let type = _.get(data, 'content_type');

  if (type === 'PER_FORM') {
    name = _.get(data, 'form.form_name');
    let vname = _.get(data, 'view.view_name');

    if (vname) name += `[${vname}]`;
  } else if (type === 'PER_REPORT') {
    name = _.get(data, 'report.title');
  } else if (type === 'PER_API') {
    name = _.get(data, 'api.api_name');
  }

  return name;
};

const handleDragDrop = (node, relaNode, relaPos, evt) => {
  //
  let cdata = _.get(node, 'data');
  let rdata = _.get(relaNode, 'data');

  let isGroup = $menuUtils._isGroup(cdata);
  let isRelaGroup = $menuUtils._isGroup(rdata);
  let relaId = -1;
  let dataId = null;

  if (!cdata) return;

  if (isRelaGroup) {
    relaId = _.get(rdata, 'group_id');
  } else {
    relaId = _.get(rdata, 'content_id');
  }

  if (isGroup) {
    dataId = _.get(cdata, 'group_id');
    api.group.changeDir(dataId, relaId, relaPos, isRelaGroup);
  } else {
    dataId = _.get(cdata, 'content_id');
    api.menu.changeDir(dataId, relaId, relaPos, isRelaGroup);
  }
  // console.log(node, lastNode, relaPos, evt);
};

const handleClearSelect = () => {
  try {
    menutreeRef.value.setCurrentNode({ tid: null });
  } catch (e) {
    // e.message
  }

  currentData.value = {};
  // form.value = {}; // _.clone(DEFAULT_FORM);
};

const selectDefaultMenu = () => {
  // if (currentData.value) return;

  let dftId = props.tid;
  if (!dftId) {
    let menu = $utils.getTreeDataFn(
      props.treeData,
      (nodeData) => nodeData && nodeData.content_id > 0,
      'subs'
    );
    dftId = _.get(menu, `tid`);
  }
  if (!dftId) return;

  let data = $utils.getTreeData(props.treeData, 'tid', dftId, 'subs');
  if (data) {
    handleClick(data);
    expandedKeys.value.push(dftId);
    menutreeRef.value.setCurrentKey(dftId);
  }
};

const refreshCurrentNode = async (tid) => {
  emit('refreshTid', tid)
  // currentSelectedId.value = tid;
  /*await init();

  if (!tid) return;
  let paths = $utils.getTreePath(tid, props.treeData, 'tid', 'subs', true);
  let info = _.find(paths, { tid: tid });

  expandedKeys.value = _.map(paths, 'tid');
  handleClick(info);*/
};

const handleClick = (data, node, ele) => {
  // this.chooseNode(data);
  // actionType.value = 'view';
  currentData.value = data;
  // form.value = _.cloneDeep(currentData.value);

  if (menutreeRef.value.store.nodesMap && menutreeRef.value.store.nodesMap[data.tid]) {
    menutreeRef.value.store.nodesMap[data.tid].expanded = true;
  }

  emit('select', data);
};

const handleShowDelete = async (dt) => {
  if (!dt) return;

  let isMbGroup = $menuUtils._isGroup(dt);
  let msg = `确定删除${isMbGroup ? '分组' : '菜单'}【${dt.name}】?`;
  $jui
    .confirm(msg, '删除确认')
    .then(async () => {
      let id = dt.id;
      let ret = null;

      if (isMbGroup) {
        ret = await api.group.removeGroup(id);
      } else {
        ret = await api.menu.removeMenu(id);
      }

      if (!ret) {
        return;
      }

      let parent_id = null;

      if (isMbGroup) {
        parent_id = _.get(dt, 'parent_id');
      } else {
        parent_id = _.get(dt, 'content_group_id');
      }

      let tid = `g_${parent_id}`;

      handleClearSelect();

      emit('actionRemove', tid);
      // await refreshCurrentNode(tid);
      // await init();
    })
    .catch((e) => {});
};

const showNodeMorePopover = (e, data) => {
  popData.value = data;
  nodeMorePopoverShow.value = true;
  nodeMorePopoverTrigger.value = e.target;
};

const handleRemoveShow = () => {
  handleShowDelete(popData.value);
};

const handleCreateGroup = () => {
  emit('actionCreate', popData.value, 'createGroup');
};

const handleCreateMenu = () => {
  emit('actionCreate', popData.value, 'createMenu');
};

const handleCreatePermission = () => {
  emit('actionCreate', popData.value, 'createPermission');
};

const handleUpdate = () => {
  emit('actionUpdate', popData.value, 'edit');
};

watch(
  () => [ props.treeData, props.tid ],
  () => {
    selectDefaultMenu();
  }
);
</script>

<template>
  <el-scrollbar class="app-form-items h-full flex-1" :options="{}" v-bind="$attrs">
    <el-tree
      ref="menutreeRef"
      class="menu-custom-tree flex-1 h-full overflow-y-auto"
      :data="treeData"
      node-key="tid"
      :highlight-current="true"
      default-expand-all
      :expand-on-click-node="false"
      :default-expanded-keys="expandedKeys"
      :props="treeSetting"
      :filter-node-method="filterNode"
      draggable
      @node-drop="handleDragDrop"
      @click.native.stop
      @node-click="handleClick"
    >
      <template #default="{ node, data }">
        <span
          class="menu-custom-tree-node menu-icon-node menu-icon-container"
          :style="$menuUtils.getIconStyleVar(data)"
        >
          <span
            class="menu-custom-icon menu-icon"
            :class="{
              'is-app': $menuUtils.isApp(data),
              'is-group': $menuUtils.isGroup(data)
            }"
          >
            <JIcon v-if="data.loading" :icon="DFT_ICONS.loadingSpinner" />
            <JIcon v-else-if="$menuUtils.isGroup(data)" :icon="$menuUtils.getIconDefault(data)" />
            <JIcon v-else-if="getNodeIconFont(data)" :icon="getNodeIconFont(data)" />
            <JIcon v-else :icon="$menuUtils.getIconDefault(data)" />
          </span>
          <span>{{ getNodeName(data) }}</span>
          <JIcon
            v-if="$menuUtils.isApp(data)"
            :icon="DFT_ICONS.app"
            class="app-icon"
            v-tippy
            content="应用"
          />
          <!-- fa-creative-commons-pd -->
          <JIcon
            v-if="$menuUtils.isWhite(data, 1)"
            :icon="DFT_ICONS.white"
            class="app-icon"
            v-tippy
            content="白名单（仅菜单）"
            style="transform: scale(0.8)"
          />
          <JIcon
            v-if="$menuUtils.isWhite(data, 2)"
            :icon="DFT_ICONS.white"
            class="app-icon"
            v-tippy
            content="白名单（菜单 & 数据）"
            style="transform: scale(0.8)"
          />
          <JIcon
            v-if="$menuUtils.ttyIsMgr(data.tty)"
            :icon="DFT_ICONS.mgr"
            class="app-icon btn-more right-3"
          />
          <JIcon
            v-if="$menuUtils.ttyIsH5(data.tty)"
            :icon="DFT_ICONS.h5"
            class="app-icon btn-more right-2"
          />
          <JIcon
            v-if="$menuUtils.ttyIsWeb(data.tty)"
            :icon="DFT_ICONS.pc"
            class="app-icon btn-more right-1"
          />
          <JIcon
            :icon="DFT_ICONS.more"
            class="btn-more"
            @click.stop="showNodeMorePopover($event, data)"
          />
        </span>
      </template>
    </el-tree>
  </el-scrollbar>

  <el-popover
    v-model:visible="nodeMorePopoverShow"
    ref="nodeMorePopover"
    popper-class="popover-dropdown-menu el-dropdown-menu--small"
    placement="right-start"
    :virtual-ref="nodeMorePopoverTrigger"
    width="auto"
    trigger="manual"
  >
    <ul class="el-dropdown-menu el-dropdown__popper">
      <template v-if="!$menuUtils.isMenu(popData)">
        <li class="el-dropdown-menu__item" @click="handleCreateGroup">
          <JIcon :icon="DFT_ICONS.add" /> 子分组
        </li>
        <li class="el-dropdown-menu__item" @click="handleCreateMenu">
          <JIcon :icon="DFT_ICONS.add" /> 子菜单
        </li>
      </template>
      <li
        class="el-dropdown-menu__item"
        :class="{
          'el-dropdown-menu__item--divided': !$menuUtils.isMenu(popData)
        }"
        @click="handleUpdate"
      >
        <JIcon :icon="DFT_ICONS.edit" />
        修改
      </li>
      <li @click="handleRemoveShow" class="el-dropdown-menu__item">
        <JIcon :icon="DFT_ICONS.delete" />
        删除
      </li>
    </ul>
  </el-popover>
</template>
<style lang="scss" scoped>
.menu-custom-tree-node {
  width: 100%;
  position: relative;

  .btn-more {
    display: none;
    position: absolute;
    /*top: 0px;*/
    right: 5px;
    font-size: 12px;
    color: #999;
    width: 18px;
    height: 18px;
    border-radius: 5px;
    text-align: center;
    line-height: 18px;
    top: 50%;
    transform: translateY(-50%);

    &:hover {
      color: #333;
      background: #eee;
    }
  }

  .right-1,
  .right-2,
  .right-3,
  .right-4,
  .right-5,
  .right-6 {
    right: 22px;
    transform: translateY(-50%) scale(0.7);
    display: block;
  }
  .right-2 {
    right: 33px;
  }
  .right-3 {
    right: 44px;
  }
  .right-4 {
    right: 55px;
  }

  &:hover {
    .btn-more {
      display: block;
    }
  }
}
</style>
